﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WindowsInput;
using WindowsInput.Native;

namespace LessonStudio.UI
{
    /// <summary>
    /// Interaction logic for LessonViewWnd.xaml
    /// </summary>
    public partial class LessonViewWnd : UserControl
    {
        public event Action OnCancel;
        public LessonViewWnd(Models.AppSetting appSetting, Models.LessonDescription lesson)
        {
            InitializeComponent();
            _appSetting = appSetting;
            _lesson = lesson;
            InitUI();
            BindEvents();
        }

        #region 事件处理
        private void OnWndLoaded(object sender, RoutedEventArgs e)
        {
            //
            canvasInk.DefaultDrawingAttributes.Color = Colors.Black;
            canvasInk.DefaultDrawingAttributes.Width = _penThickness;
            canvasInk.DefaultDrawingAttributes.Height = _penThickness;
            btnPenSetting.ToolTip = string.Format("画笔粗细为: {0}像素，颜色为：黑色", _penThickness);

            canvasInk.Focus();

            //
            panelProgress.Visibility = Visibility.Visible;
            Task.Run(() => {
                try
                {
                    LoadLesson();
                    _currentPage = 0;
                    this.Dispatcher.Invoke(() => {
                        GotoLesson(_currentPage);
                    });
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex);
                }
                finally
                {
                    this.Dispatcher.Invoke(() => {
                        panelProgress.Visibility = Visibility.Collapsed;
                    });
                }
            });

        }

        private void OnWindowKeyDown(object sender, KeyEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(e.KeyboardDevice.Modifiers);
            System.Diagnostics.Debug.WriteLine(e.Key);
            //
            if (e.Key == Key.Right)
            {
                //翻页
                //NextPage();

                btnNextPage.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                e.Handled = true;
            }
            else if (e.Key == Key.Left)
            {
                //翻页
                btnPrevPage.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                e.Handled = true;
                //PrevPage();
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.Up)
            {
                First();
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.Down)
            { 
                Last();
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.O)
            {
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.C)
            {
                btnClearInk.RaiseEvent(e);
                e.Handled = true;
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.E)
            {
                //删除状态
                //canvasInk.EditingMode = InkCanvasEditingMode.EraseByStroke;
            }
            else if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.H)
            {
                //隐藏上面的各个按钮
            }
            else if (e.Key == Key.Back)
            {
                //返回
                Close();
                e.Handled = true;
            }
        }

        private void OnButtonOpenRecordToolClick(object sender, RoutedEventArgs e)
        {
            //打开录制工具:XBOX
            //模拟键盘：Win+G
            var ctrlAndAlt = new List<VirtualKeyCode>()
            { VirtualKeyCode.LWIN, VirtualKeyCode.VK_G };
            InputSimulator inputSimulator = new InputSimulator();
            inputSimulator.Keyboard.ModifiedKeyStroke(ctrlAndAlt, VirtualKeyCode.MULTIPLY);
        }

        private void OnButtonPenClick(object sender, RoutedEventArgs e)
        {
            //画笔
            btnPen.IsChecked = true;
            btnHighlighter.IsChecked = false;
            canvasInk.DefaultDrawingAttributes.IsHighlighter = false;
        }

        private void OnButtonHighlighterClick(object sender, RoutedEventArgs e)
        {
            btnPen.IsChecked = false;
            btnHighlighter.IsChecked = true;
            canvasInk.DefaultDrawingAttributes.IsHighlighter = true;
        }

        private void OnButtonModeDrawClick(object sender, RoutedEventArgs e)
        {
            //画笔
            btnModeRubber.IsChecked = false;
            btnModeDraw.IsChecked = true;
            canvasInk.EditingMode =  InkCanvasEditingMode.Ink;
            //canvasInk.Cursor = Cursors.Pen;
        }

        private void OnButtonModeRubberClick(object sender, RoutedEventArgs e)
        {
            btnModeRubber.IsChecked = true;
            btnModeDraw.IsChecked = false;
            canvasInk.EditingMode = InkCanvasEditingMode.EraseByStroke;
            //canvasInk.Cursor = Cursors.Cross;
        }

        private void OnButtonColorBlackClick(object sender, RoutedEventArgs e)
        {
            //黑色
            btnColorBlack.IsChecked = true;
            btnColorBlue.IsChecked = false;
            btnColorRed.IsChecked = false;
            btnColorYellow.IsChecked = false;
            _penColor = Colors.Black;
            canvasInk.DefaultDrawingAttributes.Color = Colors.Black;
            UpdatePenButtonTooltip();
        }

        private void OnButtonColorRedClick(object sender, RoutedEventArgs e)
        {
            //红色
            btnColorBlack.IsChecked = false;
            btnColorBlue.IsChecked = false;
            btnColorRed.IsChecked = true;
            btnColorYellow.IsChecked = false;
            _penColor = Colors.Red;
            canvasInk.DefaultDrawingAttributes.Color = Colors.Red;
            UpdatePenButtonTooltip();
        }

        private void OnButtonColorYellowClick(object sender, RoutedEventArgs e)
        {
            //黄色
            btnColorBlack.IsChecked = false;
            btnColorBlue.IsChecked = false;
            btnColorRed.IsChecked = false;
            btnColorYellow.IsChecked = true;
            _penColor = Colors.Yellow;
            canvasInk.DefaultDrawingAttributes.Color = Colors.Yellow;
            UpdatePenButtonTooltip();
        }

        private void OnButtonColorBlueClick(object sender, RoutedEventArgs e)
        {
            //蓝色
            btnColorBlack.IsChecked = false;
            btnColorBlue.IsChecked = true;
            btnColorRed.IsChecked = false;
            btnColorYellow.IsChecked = false;
            _penColor = Colors.Blue;
            canvasInk.DefaultDrawingAttributes.Color = Colors.Blue;
            UpdatePenButtonTooltip();
        }

        private void OnButtonZoomFitWidthClick(object sender, RoutedEventArgs e)
        {
            //宽度
            moonPdfPanel.ZoomToWidth();
            btnZoom.ToolTip = btnZoomFitWidth.ToolTip;
        }

        private void OnButtonZoomFitHeightClick(object sender, RoutedEventArgs e)
        {
            moonPdfPanel.ZoomToHeight();
            btnZoom.ToolTip = btnZoomFitHeight.ToolTip;
        }

        private void OnButtonZoomSourceClick(object sender, RoutedEventArgs e)
        {
            moonPdfPanel.Zoom(1.0);
            btnZoom.ToolTip = btnZoomSource.ToolTip;
        }

        private void OnThicknessValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            _penThickness = e.NewValue;
            canvasInk.DefaultDrawingAttributes.Width = _penThickness;
            canvasInk.DefaultDrawingAttributes.Height = _penThickness;
            UpdatePenButtonTooltip();
        }

        private void OnButtonPrevPageClick(object sender, RoutedEventArgs e)
        {
            //首先备份画笔
            try
            {
                SaveCanvas();
                if (_currentPage >= 0 && _currentPage < _lessonViewItems.Count)
                {
                    //
                    var strokes = _lessonViewItems[_currentPage].Prev();
                    if (strokes != null)
                    {
                        canvasInk.Strokes.Clear();
                        canvasInk.Strokes.Add(strokes);
                    }
                    else
                    {
                        if (_currentPage > 0)
                        {
                            _currentPage--;
                            GotoLesson(_currentPage);
                        }
                    }
                }
            }
            catch
            {
            }
        }

        private void OnButtonNextPageClick(object sender, RoutedEventArgs e)
        {
            try
            {
                //首先备份画笔
                SaveCanvas();
                if (_currentPage >= 0 && _currentPage < _lessonViewItems.Count)
                {
                    //
                    var strokes = _lessonViewItems[_currentPage].Next();
                    if (strokes != null)
                    {
                        canvasInk.Strokes.Clear();
                        canvasInk.Strokes.Add(strokes);
                    }
                    else
                    {
                        if (_currentPage < (_lessonViewItems.Count - 1))
                        {
                            _currentPage++;
                            GotoLesson(_currentPage);
                        }
                    }
                }
            }
            catch
            {
            }
        }

        private void OnButtonClearInkClick(object sender, RoutedEventArgs e)
        {
            //首先备份画笔
            SaveCanvas();
            if (_currentPage >= 0 && _currentPage < _lessonViewItems.Count)
            {
                //清除
                _lessonViewItems[_currentPage].Add();
                canvasInk.Strokes.Clear();
            }
        }

        #endregion

        #region 辅助函数
        Models.AppSetting _appSetting = null;
        Models.LessonDescription _lesson = null;
        List<Models.LessonViewItem> _lessonViewItems = new List<Models.LessonViewItem>();
        int _currentPage = -1;
        int _prevPage = -1;
        Color _penColor = Colors.Black;
        double _penThickness = 6;
        int _imageFileIndex = 0;
        string _imageDir = null;

        void InitUI()
        {
            //
            var lessonDir = System.IO.Path.Combine(_appSetting.LessonBaseDir, _lesson.Name);
            for (int i = 0; i < 1000; i++)
            {
                _imageDir = System.IO.Path.Combine(lessonDir, string.Format("{0:D3}", i + 1));
                if (!System.IO.Directory.Exists(_imageDir))
                {
                    System.IO.Directory.CreateDirectory(_imageDir);
                    break;
                }
            }
        }

        void BindEvents()
        {
            this.Loaded += OnWndLoaded;
            this.KeyDown += OnWindowKeyDown;
            btnPrevPage.Click += OnButtonPrevPageClick;
            btnNextPage.Click += OnButtonNextPageClick;
            btnClearInk.Click += OnButtonClearInkClick;
            btnOpenRecordTool.Click += OnButtonOpenRecordToolClick;
            btnPen.Click += OnButtonPenClick;
            btnHighlighter.Click += OnButtonHighlighterClick;
            btnModeDraw.Click += OnButtonModeDrawClick;
            btnModeRubber.Click += OnButtonModeRubberClick;
            btnColorBlack.Click += OnButtonColorBlackClick;
            btnColorRed.Click += OnButtonColorRedClick;
            btnColorBlue.Click += OnButtonColorBlueClick;
            btnColorYellow.Click += OnButtonColorYellowClick;
            btnZoomSource.Click += OnButtonZoomSourceClick;
            btnZoomFitHeight.Click += OnButtonZoomFitHeightClick;
            btnZoomFitWidth.Click += OnButtonZoomFitWidthClick;
            sliderThickness.ValueChanged += OnThicknessValueChanged;
            btnClose.Click += (s, e) => { Close(); };
        }

        /// <summary>
        /// 某一页的，哪个画板
        /// pdf文件的每一页都允许多次画画，全部存储下来了
        /// </summary>
        /// <param name="page"></param>
        /// <param name="idx"></param>
        void GotoLesson(int page)
        {
            //这个时候保证
            if(_lessonViewItems.Count > page)
            {
                //
                var file = _lessonViewItems[page];
                if (file.FilePath.EndsWith(".pdf"))
                {
                    var prevZoomType = moonPdfPanel.ZoomType;
                    //moonPdfPanel.Visibility = Visibility.Collapsed;

                    if(_prevPage>=0 && _lessonViewItems[_prevPage].FilePath.Equals(file.FilePath))
                    {
                        //和上一页的内容一致,不需要重复打开了
                        //moonPdfPanel.OpenFile(file.FilePath);
                    }
                    else
                    {
                        moonPdfPanel.Visibility = Visibility.Collapsed;
                        moonPdfPanel.OpenFile(file.FilePath);
                        moonPdfPanel.Visibility = Visibility.Visible;
                        moonPdfPanel.ZoomToHeight();
                        ////获取到比例关系
                        //var curZoomType = moonPdfPanel.ZoomType;
                        //switch (curZoomType)
                        //{
                        //    case MoonPdfLib.ZoomType.Fixed:
                        //        moonPdfPanel.Zoom(1.0);
                        //        break;
                        //    case MoonPdfLib.ZoomType.FitToHeight:
                        //        moonPdfPanel.ZoomToHeight();
                        //        break;
                        //    case MoonPdfLib.ZoomType.FitToWidth:
                        //        moonPdfPanel.ZoomToWidth();
                        //        break;
                        //}
                    }

                    moonPdfPanel.GotoPage(file.Page);
                    canvasInk.Strokes.Clear();
                    var strokes = file.Current();
                    if (strokes != null)
                    {
                        canvasInk.Strokes.Add(strokes);
                    }
                }

                _prevPage = page;
            }
        }

        void First()
        {
            //首先备份画笔
            try
            {
                SaveCanvas();
                if (_lessonViewItems.Count > 0)
                {
                    _currentPage = 0;
                    GotoLesson(_currentPage);
                }
            }
            catch
            {
            }

        }

        void Last()
        {
            //首先备份画笔
            try
            {
                SaveCanvas();
                if(_lessonViewItems.Count > 0)
                {
                    _currentPage = _lessonViewItems.Count - 1;
                    GotoLesson(_currentPage);
                }
            }
            catch
            {
            }

        }

        void Close()
        {
            SaveImage(); 
            OnCancel?.Invoke();
        }

        void LoadLesson()
        {
            //直接创建所有页面
            _lessonViewItems.Clear();
            var lessonDir = System.IO.Path.Combine(_appSetting.LessonBaseDir, _lesson.Name);
            if (!System.IO.Directory.Exists(lessonDir))
            {
                throw new Exception("课件所在的文件夹不存在");
            }

            if (_lesson.Files == null || _lesson.Files.Count == 0)
                throw new Exception("课件中没有文件");

            _lesson.Files.Sort((l, r) => { return l.Order.CompareTo(r.Order); });
            foreach (var file in _lesson.Files)
            {
                //可能需要组合出文件路径
                var filepath = System.IO.Path.Combine(lessonDir, file.FilePath);
                //使用相对路径
                if (!System.IO.File.Exists(filepath))
                {
                    throw new Exception(String.Format("课件文件{0}不存在", file.Name));
                }

                if (file.FilePath.EndsWith(".pdf"))
                {
                    //页面是从1开始的
                    this.Dispatcher.Invoke(() => {
                        try
                        {
                            moonPdfPanel.Visibility = Visibility.Collapsed;
                            moonPdfPanel.OpenFile(filepath);
                            var pages = moonPdfPanel.TotalPages;
                            for (int j = 0; j < pages; j++)
                            {
                                _lessonViewItems.Add(new Models.LessonViewItem() { FilePath = filepath, Page = j + 1, });
                            }
                        }
                        catch
                        {

                        }
                    });
                }
                else if (file.FilePath.EndsWith(".jpg"))
                {
                    _lessonViewItems.Add(new Models.LessonViewItem() { FilePath = filepath, Page = 0, });
                }
                else if (file.FilePath.EndsWith(".png"))
                {
                    _lessonViewItems.Add(new Models.LessonViewItem() { FilePath = filepath, Page = 0, });
                }
            }
        }

        void SaveCanvas()
        {
            //这个时候最好输出一些图片
            if (_currentPage >= 0 && _currentPage < _lessonViewItems.Count)
            {
                //
                //首先备份画笔
                var current = _lessonViewItems[_currentPage].Current();
                current.Clear();
                current.Add(canvasInk.Strokes);

                //
                SaveImage();
            }
        }

        void SaveImage()
        {
            try
            {
                if (!string.IsNullOrEmpty(_imageDir))
                {
                    var imageFilePath = System.IO.Path.Combine(_imageDir, string.Format("{0:D5}.jpg", _imageFileIndex++));
                    GetPicFromControl(gridPanel, imageFilePath);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }

        void UpdatePenButtonTooltip()
        {
            if(_penColor.Equals(Colors.Black))
            {
                btnPenSetting.ToolTip = string.Format("画笔粗细为: {0}像素，颜色为：黑色", _penThickness);
            }
            else if(_penColor.Equals(Colors.Red))
            {
                btnPenSetting.ToolTip = string.Format("画笔粗细为: {0}像素，颜色为：红色", _penThickness);
            }
            else if (_penColor.Equals(Colors.Yellow))
            {
                btnPenSetting.ToolTip = string.Format("画笔粗细为: {0}像素，颜色为：黄色", _penThickness);
            }
            else if (_penColor.Equals(Colors.Blue))
            {
                btnPenSetting.ToolTip = string.Format("画笔粗细为: {0}像素，颜色为：蓝色", _penThickness);
            }
            else
            {
                btnPenSetting.ToolTip = string.Format("画笔粗细为: {0}像素，颜色为：{1}", _penThickness, _penColor);
            }
        }

        //截屏函数
        private void GetPicFromControl(FrameworkElement element, String outputPath, String type= "JPEG")
        {
            //96为显示器DPI
            //位图 宽度  高度   水平DPI  垂直DPI  位图的格式    
            //高度+100保证整个图都能截取: 我们这里不加
            //
            //var dpi = DisplayInformation.GetForCurrentView().LogicalDpi;
            //var bmp = new WriteableBitmap((int)element.ActualWidth, (int)element.ActualHeight, 96., 96, PixelFormats.Pbgra32, null);
            //这里的宽度和高度，以及分辨率很大程度上决定了图片的质量
            //WPF默认是96dpi渲染
            var bitmapRender = new RenderTargetBitmap((int)element.ActualWidth * 3, (int)element.ActualHeight * 3, 96 * 3, 96 * 3, PixelFormats.Pbgra32);
            //控件内容渲染RenderTargetBitmap
            bitmapRender.Render(element);
            BitmapEncoder encoder = null;
            //选取编码器
            switch (type.ToUpper())
            {
                case "BMP":
                    encoder = new BmpBitmapEncoder();
                    break;
                case "GIF":
                    encoder = new GifBitmapEncoder();
                    break;
                case "JPEG":
                    var jpeg = new JpegBitmapEncoder();
                    jpeg.QualityLevel = 80;
                    encoder = jpeg;
                    break;
                case "PNG":
                    encoder = new PngBitmapEncoder();
                    break;
                case "TIFF":
                    encoder = new TiffBitmapEncoder();
                    break;
                default:
                    break;
            }

            //对于一般的图片，只有一帧，动态图片是有多帧的。
            encoder.Frames.Add(BitmapFrame.Create(bitmapRender));//添加图
            if (!Directory.Exists(System.IO.Path.GetDirectoryName(outputPath)))
                Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outputPath));
            using (var file = File.Create(outputPath))//存储文件
                encoder.Save(file);
        }
        #endregion
    }
}
